﻿/*
jsonAspNet v1.1, copyright (c) 2009 Chris O'Brien, prettycode.org
Requires jQuery and JSON.stringify()
*/

(function() {

    $.jsonAspNet = function(page, webMethod, data, success, error) {
        ///	<summary>
        /// <para>
        ///     Use $.jsonAspNet() to send Ajax requests to ASP.NET web services
        ///     using JSON as the interchange format. The function is a simple
        ///     wrapper for $.ajax() that ensures the options are appropriately
        ///     specified and that any data sent is correctly serialized. Arguments
        ///     may be overloaded with any of these combination:
        /// </para>
        /// <para>
        ///     A) $.jsonAspNet(page, webMethod, data)
        ///     B) $.jsonAspNet(page, webMethod, data, success)
        ///     C) $.jsonAspNet(page, webMethod, data, success, error)
        ///     D) $.jsonAspNet(page, webMethod, success, error)
        ///     E) $.jsonAspNet(page, webMethod, success)
        /// </para>
        /// </summary>  

        // function(page, webMethod, data, success, error)
        // Argument overloading for: (page, webMethod, success, error)

        if (
            typeof data === "function" &&
            typeof success === "function" &&
            typeof error === "undefined"
        ) {
            error = success;
            success = data;
            data = null;
        }

        // Argument overloading for (page, webMethod, success)

        else if (
            typeof data === "function" &&
            typeof success === "undefined" &&
            typeof error === "undefined"
        ) {
            success = data;
            data = null;
        }

        // ASP.NET returns .NET DateTime objects as strings in this format: 
        // "/Date(x)/" where x is the unix time in ms. JSON.parse() errors out
        // when trying to convert such a date. dateFix() below will convert all
        // "/Date(x)/" strings (at any depth) to JavaScript Date objects.

        function dateFix(obj) {

            if (obj == null) {
                return obj;
            }

            // ASP.NET JSON date?

            if (typeof obj === "string") {
                var match = obj.match(/^\/Date\((\d+)\)\/$/);

                if (!match) {
                    return obj;
                }

                return new Date(parseInt(match[1]));
            }

            // string or number

            if (typeof obj !== "object") {
                return obj;
            }

            // array or object

            jQuery.each(obj, function(key, val) {
                obj[key] = dateFix(val);
            });

            return obj;
        }

        // Automatically unwrap the return value from the service

        function successWrapper(data, textStatus) {
            if (success) {
                success(dateFix(data.d), textStatus);
            }
        };

        // Default error message 

        if (!error) {
            error = function(xhr) {
                if (xhr.responseText) {
                    if ((exception = eval("(" + xhr.responseText + ")"))) {
                        alert(exception.Message);
                        //alert(exception.StackTrace);
                    }
                    else {
                        alert(xhr.responseText);
                    }
                }
            };
        }

        // Send request 

        return $.ajax({
            type: "POST",
            data: (!data ? "{}" : JSON.stringify(data)),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            url: page + "/" + webMethod,
            success: successWrapper,
            error: error
        });
    };
})();